package com.geese.common.shiro.realm;

import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.geese.common.entity.Permission;
import com.geese.common.entity.Role;
import com.geese.common.util.JSONUtil;
import com.geese.module.security.service.PermissionService;
import com.geese.module.security.service.RoleService;
import com.geese.module.user.model.SecurityUser;
import com.geese.module.user.service.UserService;
import com.geese.util.CommonUtil;
import com.google.common.collect.Sets;

public class StatelessRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private PermissionService permissionService;

	@Override
	public boolean supports(AuthenticationToken token) {
		return token instanceof StatelessToken;
	}

	@Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //根据用户名查找角色，请根据需求实现
        String token = (String) principals.getPrimaryPrincipal();
        SecurityUser user = userService.getUser(token);
        List<Role> roleList = roleService.listByUserId(user.getUserId());
        List<Permission> permissionList = permissionService.listByRoleIds(CommonUtil.getRoleIdSet(roleList));
        SimpleAuthorizationInfo authorizationInfo =  new SimpleAuthorizationInfo();
        authorizationInfo.addRoles(getRoleNameSet(roleList));
        authorizationInfo.addStringPermissions(getPermissionSet(permissionList));
        System.out.println(JSONUtil.objectToJson(authorizationInfo.getStringPermissions()));
        return authorizationInfo;
    }

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		StatelessToken statelessToken = (StatelessToken) token;
		SecurityUser user = userService.getUser(statelessToken.getToken());
		if (user == null) {
			throw new UnknownAccountException();
		}
		return new SimpleAuthenticationInfo(statelessToken.getToken(), statelessToken.getToken(), getName());
	}

	private Set<String> getRoleNameSet(List<Role> roleList) {
		Set<String> result = Sets.newHashSet();
		for (Role role : roleList) {
			result.add(role.getName());
		}
		return result;
	}

	private Set<String> getPermissionSet(List<Permission> permissionList) {
		Set<String> result = Sets.newHashSet();
		for (Permission permission : permissionList) {
			if(StringUtils.isNotEmpty(permission.getPermission())) {
				result.add(permission.getPermission());
			}
		}
		return result;
	}

}
